package me.kagami.exex;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import me.kagami.exex.intercepter.InsertDataIntercepter;
import me.kagami.exex.intercepter.IntercepterChain;
import me.kagami.exex.registry.CellStyleService;

public class CommonExcelClient {
	protected Context context;
	protected Workbook workbook;
	private FileInputStream fis;
	private FileOutputStream fos;

	public CommonExcelClient(String inputFilePath, String outputFilePath, List<?> dataList) throws Exception {
		fis = new FileInputStream(new File(inputFilePath));
		fos = new FileOutputStream(new File(outputFilePath));
		workbook = new XSSFWorkbook(fis);
		context = new Context(workbook, dataList);
	}

	public void assembleDyna(int beginRowNum, int beginColNum) throws IOException, IllegalArgumentException, IllegalAccessException {
		Sheet sheet = workbook.getSheetAt(0);
		sheet.autoSizeColumn(0);
		context.initCellStyleList(sheet);

		IntercepterChain.beforeAssembleData(context.getIntercepters(), sheet, context.getDataList(), beginRowNum, beginColNum);

		for (int rowIndex = 0; rowIndex < context.getDataList().size(); rowIndex++) {
			Row row = sheet.getRow(beginRowNum + rowIndex);
			if (row == null) {
				row = sheet.createRow(beginRowNum + rowIndex);
			}
			handleCellOfRow(beginColNum, rowIndex, row);
		}
		IntercepterChain.afterAssembleData(context.getIntercepters(), sheet, context.getDataList());

		workbook.write(fos);
		workbook.close();
		fis.close();
		fos.close();
	}

	private void handleCellOfRow(int beginColNum, int rowIndex, Row row) throws IllegalAccessException {
		IntercepterChain.beforeInsertRow(context.getIntercepters(), row, context.getDataList().get(rowIndex), rowIndex);
		List<Field> fields = context.getDataFields(rowIndex);
		for (int cellIndex = 0; cellIndex < fields.size(); cellIndex++) { // 遍历所有属性
			Cell cell = row.getCell(cellIndex + beginColNum);
			if (cell == null) {
				cell = row.createCell(cellIndex + beginColNum);
			}
			CellStyleService.assignCellStyle(cell, cellIndex, context.getCellStyleList());
			insertCell(rowIndex, fields, cellIndex, cell);
		}
		IntercepterChain.afterInsertRow(context.getIntercepters(), row, context.getDataList().get(rowIndex), rowIndex);
	}

	private void insertCell(int rowIndex, List<Field> fields, int cellIndex, Cell cell) throws IllegalAccessException {
		fields.get(cellIndex).setAccessible(true);
		IntercepterChain.beforeInsertData(context.getIntercepters(), cell, fields.get(cellIndex), rowIndex, cellIndex);
		String dataStr = (fields.get(cellIndex).get(context.getDataList().get(rowIndex))).toString();
		try {
			cell.setCellValue(Double.parseDouble(dataStr));
		} catch (Exception e) {
			cell.setCellValue(dataStr);
		}
		IntercepterChain.afterInsertData(context.getIntercepters(), cell, fields.get(cellIndex), rowIndex, cellIndex);
	}

	public void addIntercepter(InsertDataIntercepter insertDataIntercepter) {
		this.context.addIntercepter(insertDataIntercepter);

	}
}
